home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Tcl-Tk 8.0 / Pre-installed version / tcl8.0 / win / stub16.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-08-15  |  5.5 KB  |  199 lines  |  [TEXT/CWIE]

  1. /* 
  2.  * stub16.c 
  3.  *
  4.  *    A helper program used for running 16-bit DOS applications under
  5.  *    Windows 95.
  6.  *
  7.  * Copyright (c) 1996 by Sun Microsystems, Inc.
  8.  *
  9.  * See the file "license.terms" for information on usage and redistribution
  10.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  *
  12.  * SCCS: @(#) stub16.c 1.5 96/12/11 20:01:58
  13.  */
  14.  
  15. #define STRICT
  16.  
  17. #include <windows.h>
  18. #include <stdio.h>
  19.  
  20. static HANDLE        CreateTempFile(void);
  21.  
  22. /*
  23.  *---------------------------------------------------------------------------
  24.  *
  25.  * main
  26.  *
  27.  *    Entry point for the 32-bit console mode app used by Windows 95 to
  28.  *    help run the 16-bit program specified on the command line.
  29.  *
  30.  *    1. EOF on a pipe that connects a detached 16-bit process and a
  31.  *    32-bit process is never seen.  So, this process runs the 16-bit
  32.  *    process _attached_, and then it is run detached from the calling
  33.  *    32-bit process.  
  34.  * 
  35.  *    2. If a 16-bit process blocks reading from or writing to a pipe,
  36.  *    it never wakes up, and eventually brings the whole system down
  37.  *    with it if you try to kill the process.  This app simulates
  38.  *    pipes.  If any of the stdio handles is a pipe, this program
  39.  *    accumulates information into temp files and forwards it to or
  40.  *    from the DOS application as appropriate.  This means that this
  41.  *    program must receive EOF from a stdin pipe before it will actually
  42.  *    start the DOS app, and the DOS app must finish generating stdout
  43.  *    or stderr before the data will be sent to the next stage of the
  44.  *    pipe.  If the stdio handles are not pipes, no accumulation occurs
  45.  *    and the data is passed straight through to and from the DOS
  46.  *    application.
  47.  *
  48.  * Results:
  49.  *    None.
  50.  *
  51.  * Side effects:
  52.  *    The child process is created and this process waits for it to
  53.  *    complete.
  54.  *
  55.  *---------------------------------------------------------------------------
  56.  */
  57.  
  58. int
  59. main()
  60. {
  61.     DWORD dwRead, dwWrite;
  62.     char *cmdLine;
  63.     HANDLE hStdInput, hStdOutput, hStdError;
  64.     HANDLE hFileInput, hFileOutput, hFileError;
  65.     STARTUPINFO si;
  66.     PROCESS_INFORMATION pi;
  67.     char buf[8192];
  68.     DWORD result;
  69.  
  70.     hFileInput = INVALID_HANDLE_VALUE;
  71.     hFileOutput = INVALID_HANDLE_VALUE;
  72.     hFileError = INVALID_HANDLE_VALUE;
  73.     result = 1;
  74.  
  75.     /*
  76.      * Don't get command line from argc, argv, because the command line
  77.      * tokenizer will have stripped off all the escape sequences needed
  78.      * for quotes and backslashes, and then we'd have to put them all
  79.      * back in again.  Get the raw command line and parse off what we
  80.      * want ourselves.  The command line should be of the form:
  81.      *
  82.      * stub16.exe program arg1 arg2 ...
  83.      */
  84.  
  85.     cmdLine = strchr(GetCommandLine(), ' ');
  86.     if (cmdLine == NULL) {
  87.     return 1;
  88.     }
  89.     cmdLine++;
  90.  
  91.     hStdInput = GetStdHandle(STD_INPUT_HANDLE);
  92.     hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
  93.     hStdError = GetStdHandle(STD_ERROR_HANDLE);
  94.  
  95.     if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
  96.     hFileInput = CreateTempFile();
  97.     if (hFileInput == INVALID_HANDLE_VALUE) {
  98.         goto cleanup;
  99.     }
  100.     while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
  101.         if (dwRead == 0) {
  102.         break;
  103.         }
  104.         if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
  105.         goto cleanup;
  106.         }
  107.     }
  108.     SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
  109.     SetStdHandle(STD_INPUT_HANDLE, hFileInput);
  110.     }
  111.     if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
  112.     hFileOutput = CreateTempFile();
  113.     if (hFileOutput == INVALID_HANDLE_VALUE) {
  114.         goto cleanup;
  115.     }
  116.     SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
  117.     }
  118.     if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
  119.     hFileError = CreateTempFile();
  120.     if (hFileError == INVALID_HANDLE_VALUE) {
  121.         goto cleanup;
  122.     }
  123.     SetStdHandle(STD_ERROR_HANDLE, hFileError);
  124.     }
  125.  
  126.     ZeroMemory(&si, sizeof(si));
  127.     si.cb = sizeof(si);
  128.     if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, 
  129.         &pi) == FALSE) {
  130.     goto cleanup;
  131.     }
  132.  
  133.     WaitForInputIdle(pi.hProcess, 5000);
  134.     WaitForSingleObject(pi.hProcess, INFINITE);
  135.     CloseHandle(pi.hProcess);
  136.     CloseHandle(pi.hThread);
  137.     result = 0;
  138.  
  139.     if (hFileOutput != INVALID_HANDLE_VALUE) {
  140.     SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
  141.     while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
  142.         if (dwRead == 0) {
  143.         break;
  144.         }
  145.         if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
  146.         break;
  147.         }
  148.     }
  149.     }
  150.     if (hFileError != INVALID_HANDLE_VALUE) {
  151.     SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
  152.     while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
  153.         if (dwRead == 0) {
  154.         break;
  155.         }
  156.         if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
  157.         break;
  158.         }
  159.     }
  160.     }
  161.  
  162. cleanup:
  163.     if (hFileInput != INVALID_HANDLE_VALUE) {
  164.     CloseHandle(hFileInput);
  165.     }
  166.     if (hFileOutput != INVALID_HANDLE_VALUE) {
  167.     CloseHandle(hFileOutput);
  168.     }
  169.     if (hFileError != INVALID_HANDLE_VALUE) {
  170.     CloseHandle(hFileError);
  171.     }
  172.     CloseHandle(hStdInput);
  173.     CloseHandle(hStdOutput);
  174.     CloseHandle(hStdError);
  175.     ExitProcess(result);
  176.     return 1;
  177. }
  178.  
  179. static HANDLE
  180. CreateTempFile()
  181. {
  182.     char name[MAX_PATH];
  183.     SECURITY_ATTRIBUTES sa;
  184.  
  185.     if (GetTempPath(sizeof(name), name) == 0) {
  186.     return INVALID_HANDLE_VALUE;
  187.     }
  188.     if (GetTempFileName(name, "tcl", 0, name) == 0) {
  189.     return INVALID_HANDLE_VALUE;
  190.     }
  191.  
  192.     sa.nLength = sizeof(sa);
  193.     sa.lpSecurityDescriptor = NULL;
  194.     sa.bInheritHandle = TRUE;
  195.     return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa, 
  196.         CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
  197.         NULL);
  198. }
  199.